package com.ics.cmsadmin.modules.auth.service.impl;

import com.ics.cmsadmin.frame.core.annotation.CacheDbMember;
import com.ics.cmsadmin.frame.core.annotation.ClearDbMember;
import com.ics.cmsadmin.frame.core.bean.PageBean;
import com.ics.cmsadmin.frame.core.bean.PageResult;
import com.ics.cmsadmin.frame.core.enums.ApiResultEnum;
import com.ics.cmsadmin.frame.core.enums.CacheGroupEnum;
import com.ics.cmsadmin.frame.core.exception.CmsException;
import com.ics.cmsadmin.frame.core.service.TreeDataService;
import com.ics.cmsadmin.modules.auth.bean.OrganizationBean;
import com.ics.cmsadmin.modules.auth.bean.SysUser;
import com.ics.cmsadmin.modules.auth.service.OrganizationService;
import com.ics.cmsadmin.modules.system.emums.SequenceNumberEnum;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

import static com.ics.cmsadmin.modules.auth.steward.AuthRepositories.organizationDao;
import static com.ics.cmsadmin.modules.auth.steward.AuthServices.userService;
import static com.ics.cmsadmin.modules.system.steward.SystemServices.sequenceNumberService;

/**
 * sys_organization
 * Created bylvsw on 2018-29-21 10:10:05.
 */
@Service
public class OrganizationServiceImpl implements OrganizationService {

    @CacheDbMember(returnClass = OrganizationBean.class, group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public OrganizationBean queryParent(String childrenId) {
        return organizationDao.queryParent(childrenId);
    }

    @CacheDbMember(returnClass = OrganizationBean.class, group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public List<OrganizationBean> listDirectChildren(String parentId) {
        return organizationDao.listDirectChildren(parentId);
    }

    @CacheDbMember(returnClass = OrganizationBean.class, group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public OrganizationBean queryById(String id) {
        if (StringUtils.isBlank(id)){
            return null;
        }
        return organizationDao.queryById(id);
    }

    @CacheDbMember(returnClass = OrganizationBean.class, group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public PageResult<OrganizationBean> list(OrganizationBean bean, PageBean page) {
        long count = organizationDao.count(bean);
        if (count == 0){
            return new PageResult<>();
        }
        page = page == null ? new PageBean() : page;
        return PageResult.getPage(count, organizationDao.list(bean, page));
    }

    @ClearDbMember(group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public boolean insert(OrganizationBean bean) {
        if (bean == null){
            return false;
        }
        String orgId = sequenceNumberService.newSequenceNumber(SequenceNumberEnum.ORGANIZATION);
        bean.setOrgId(orgId);
        if (StringUtils.isBlank(bean.getParentId()) || StringUtils.equals(bean.getParentId(), DEFAULT_ROOT_ID)){
            bean.setParentId(DEFAULT_ROOT_ID);
            bean.setParentNode(DEFAULT_ROOT_ID);
            bean.setOrgNode(String.format("%s,%s", DEFAULT_ROOT_ID, orgId));
        }else{
            OrganizationBean parentOrgan = queryById(bean.getParentId());
            if(parentOrgan == null){
                throw new CmsException(ApiResultEnum.INSERT_TABLE_ITEM_FAIL, "父节点没有找到");
            }
            bean.setParentNode(parentOrgan.getOrgNode());
            bean.setOrgNode(String.format("%s,%s", parentOrgan.getOrgNode(), orgId));
        }
        return organizationDao.insert(bean) == 1;
    }

    @ClearDbMember(group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public boolean update(String id, OrganizationBean bean) {
        if (StringUtils.isBlank(id) || bean == null || queryById(id) == null){
            throw new CmsException(ApiResultEnum.UPDATE_TABLE_ITEM_FAIL, "参数有误");
        }
        return organizationDao.update(id, bean) == 1;
    }

    @ClearDbMember(group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public boolean delete(String id) {
        if (StringUtils.isBlank(id) || queryById(id) == null){
            throw new CmsException(ApiResultEnum.DELETE_TABLE_ITEM_FAIL, "参数有误");
        }
        if (CollectionUtils.isNotEmpty(listDirectChildren(id))){
            throw new CmsException(ApiResultEnum.DELETE_TABLE_ITEM_FAIL, "该组织存在下级节点,不能删除");
        }
        if(userService.findOne(SysUser.builder().orgId(id).build()) != null){
            throw new CmsException(ApiResultEnum.DELETE_TABLE_ITEM_FAIL, "该组织存在用户,不能删除");
        }
        return organizationDao.delete(id) == 1;
    }

    @CacheDbMember(returnClass = OrganizationBean.class, group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public OrganizationBean listAllChildren() {
        OrganizationBean parent = Optional.ofNullable(queryById(TreeDataService.DEFAULT_ROOT_ID))
            .orElse(OrganizationBean.builder()
                .orgId(TreeDataService.DEFAULT_ROOT_ID)
                .name("Boss")
                .orgNode(TreeDataService.DEFAULT_ROOT_ID)
                .parentId("0")
                .description("Boss")
                .build());
        listAllChildren(parent);
        return parent;
    }

    private void listAllChildren(OrganizationBean parent) {
        List<OrganizationBean> organizationBeans = listDirectChildren(parent.getOrgId());
        if (CollectionUtils.isEmpty(organizationBeans)) {
            return;
        }
        parent.setChildren(organizationBeans);
        for (OrganizationBean bean : organizationBeans) {
            listAllChildren(bean);
        }
    }

    @CacheDbMember(returnClass = OrganizationBean.class, group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public PageResult<OrganizationBean> listByLoginUserId(OrganizationBean organizationBean, String loginUserId, PageBean page) {
        return listByLoginUserId(organizationBean, loginUserId, page, organizationDao);
    }

    @Override
    public OrganizationBean listAllUserGroupByOrgain() {
        OrganizationBean parent = Optional.ofNullable(queryById(TreeDataService.DEFAULT_ROOT_ID))
            .orElse(OrganizationBean.builder()
                .orgId(TreeDataService.DEFAULT_ROOT_ID)
                .name("Boss")
                .orgNode(TreeDataService.DEFAULT_ROOT_ID)
                .parentId("0")
                .description("Boss")
                .build());
        PageResult<SysUser> list = userService.list(SysUser.builder().orgId(parent.getOrgId()).build(),
            new PageBean(1, Integer.MAX_VALUE));
        parent.setSysUsers(list == null ? null : list.getDataList());
        parent.setChildren(listDirectChildren(parent.getOrgId()));

        if (CollectionUtils.isNotEmpty(parent.getChildren())) {
            parent.getChildren().stream().forEach(item -> {
                PageResult<SysUser> childrenList = userService.list(SysUser.builder().orgId(item.getOrgId()).build(),
                    new PageBean(1, Integer.MAX_VALUE));
                item.setSysUsers(childrenList == null ? null : childrenList.getDataList());
            });
        }
        return parent;
    }
}
